﻿#include "lua_lv_enum.h"
#include "lua_obj.h"
#include "lua_lvgl_lib.h"

static int lua_lv_scr_act(lua_State *L)
{
    lv_obj_t *lv_obj = lv_scr_act();
    lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
    *obj = lv_obj;

    lua_pushlightuserdata(L, (void *)obj);
    return 1;
}

static int lua_lv_layer_top(lua_State *L)
{
    lv_obj_t *lv_obj = lv_layer_top();
    lua_pushlightuserdata(L, (void *)lv_obj);
    return 1;
}

static int lua_lv_layer_sys(lua_State *L)
{
    lv_obj_t *lv_obj = lv_layer_sys();
    lua_pushlightuserdata(L, (void *)lv_obj);
    return 1;
}

static int lua_lv_scr_load(lua_State *L)
{
    lv_scr_load(lua_touserdata(L, 1));
    return 0;
}

//////////////////////////////////////////////////////////////////////
static int lua_lv_obj_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_obj_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_STR);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_label_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_label_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_LABEL);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_btn_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_btn_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_BTN);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_img_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_img_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_IMG);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_arc_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_arc_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_ARC);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_bar_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_bar_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_BAR);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_checkbox_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_checkbox_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_CHECKBOX);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_btnmatrix_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_btnmatrix_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_BTNMATRIX);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_canvas_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_canvas_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_CANVAS);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_dropdown_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_dropdown_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_DROPDOWN);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_line_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_line_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_LINE);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_roller_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_roller_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_ROLLER);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_slider_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_slider_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_SLIDER);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_switch_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    lv_obj_t *lv_obj = NULL;
    lv_obj = lv_switch_create(parent);

    if (lv_obj)
    {
        lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
        *obj = lv_obj;
        luaL_setmetatable(L, META_SWITCH);
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

static int lua_lv_table_create(lua_State *L)
{
    // LUA_USER_PRINT(__func__);
    // lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    // lv_obj_t *lv_obj = NULL;
    // lv_obj = lv_tabel_create(parent);

    // if (lv_obj)
    // {
    //     lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
    //     *obj = lv_obj;
    //     luaL_setmetatable(L, META_TABLE);
    // }
    // else
    // {
    //     lua_pushnil(L);
    // }
    // return 1;
}

static int lua_lv_textarea_create(lua_State *L)
{
    // LUA_USER_PRINT(__func__);
    // lv_obj_t *parent = *(lv_obj_t **)lua_touserdata(L, 1);
    // lv_obj_t *lv_obj = NULL;
    // lv_obj = lv_texterea_create(parent);

    // if (lv_obj)
    // {
    //     lv_obj_t **obj = lua_newuserdata(L, sizeof(lv_obj_t *));
    //     *obj = lv_obj;
    //     luaL_setmetatable(L, META_TEXTAREA);
    // }
    // else
    // {
    //     lua_pushnil(L);
    // }
    // return 1;
}

static int lua_lv_anim_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_anim_t *a = (lv_anim_t *)lua_newuserdata(L, sizeof(lv_anim_t));
    lv_anim_init(a);
    luaL_setmetatable(L, META_ANIM);
    return 1;
}

static int lua_lv_style_create(lua_State *L)
{
    LUA_USER_PRINT(__func__);
    lv_style_t *a = (lv_style_t *)lua_newuserdata(L, sizeof(lv_style_t));
    lv_style_init(a);
    luaL_setmetatable(L, META_STYLE);
    return 1;
}

static int lua_auto_gc(lua_State *L)
{
    lv_obj_t *lv_obj = *(lv_obj_t **)luaL_checkudata(L, 1, META_STR);
    luaL_argcheck(L, lv_obj != NULL, 1, "invalid user data");
    if (lv_obj)
    {
        lv_obj_del(lv_obj);
    }
    return 0;
}

static const struct luaL_Reg arraylib_f[] = {
    {"scr_act", lua_lv_scr_act},
    {"layer_top", lua_lv_layer_top},
    {"layer_sys", lua_lv_layer_sys},
    {"scr_load", lua_lv_scr_load},
    LUA_LV_CREAT_RLT,
    LUA_LV_OBJ_RLT,
    {NULL, NULL}};

static const struct luaL_Reg arraylib_m[] = {
    LUA_LV_OBJ_RLT,
    {NULL, NULL}};

static const struct luaH_Reg_enum arraylib_enum[] = {
    LUA_LV_ENMU_RLT,
    {NULL, NULL}};

static const struct luaH_Reg_enum_string arraylib_string[] = {
    LUA_LV_STRING_RLT,
    {NULL, NULL}};

LUALIB_API int lua_lvgl_funinit(lua_State *L)
{
    luaL_newlib(L, arraylib_f);
    luaL_newmetatable(L, META_STR);  /* create metatable for file handles */
    lua_pushvalue(L, -1);            /* push metatable */
    lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
    luaL_setfuncs(L, arraylib_m, 0); /* add file methods to new metatable */
    lua_pop(L, 1);                   /* pop new metatable */

    add_enum(L, arraylib_enum);
    add_enum_string(L, arraylib_string);

    return 1;
}
